package com.example.demo.service.iml;

import com.example.demo.mapper.DeviceMapper;
import com.example.demo.pojo.Device;
import com.example.demo.service.DeviceService;
import com.example.demo.util.TokenUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@Service
public class DeviceServiceImpl implements DeviceService {
    private static final Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class);

    @Autowired
    private DeviceMapper deviceMapper;

    private final WebClient webClient;

    @Value("${api.version}")
    private String apiVersion;

    @Value("${api.resource-name}")
    private String resourceName;

    @Value("${api.access-key}")
    private String accessKey;

    public DeviceServiceImpl(WebClient.Builder webClientBuilder) {
        this.webClient = webClientBuilder.baseUrl("https://iot-api.heclouds.com").build();
        logger.info("设备服务初始化完成");
    }

    @Override
    public String saveDevice(String imei) {
        Device device = new Device();
        device.setImei(imei);

        int result = deviceMapper.insert(device);
        if (result > 0) {
            return "设备保存成功";
        } else {
            return "设备保存失败";
        }
    }

    @Override
    public Mono<String> queryDeviceProperty(String productId, String deviceName) {
        logger.info("开始查询设备属性，产品ID: {}，设备名称: {}", productId, deviceName);

        return Mono.fromCallable(() -> {
                    String token = TokenUtil.generateToken(apiVersion, resourceName, accessKey);
                    logger.info("Token 生成成功");
                    System.out.println(token);
                    return token;
                })
                .flatMap(token -> webClient.get()
                        .uri(uriBuilder -> uriBuilder
                                .path("/thingmodel/query-device-property")
                                .queryParam("product_id", productId)
                                .queryParam("device_name", deviceName)
                                .build())
                        .header("Accept", "application/json, text/plain, */*")
                        .header("authorization", token)
                        .retrieve()
                        .bodyToMono(String.class)
                        .doOnNext(response -> {
                            logger.info("收到来自 OneNET 的响应: {}", response);
                        })
                        .doOnError(error -> {
                            logger.error("查询设备属性时发生错误", error);
                        }))
                .doOnSuccess(result -> {
                    logger.info("设备属性查询成功完成");
                })
                .doOnError(error -> {
                    logger.error("设备属性查询过程中发生错误", error);
                });
    }

    @Override
    public Mono<String> setDeviceProperty(String productId, String deviceName, Object params) {
        logger.info("开始设置设备属性，产品ID: {}，设备名称: {}，参数: {}", productId, deviceName, params);

        return Mono.fromCallable(() -> {
                    String token = TokenUtil.generateToken(apiVersion, resourceName, accessKey);
                    logger.info("Token 生成成功: {}", token);
                    return token;
                })
                .flatMap(token -> webClient.post()
                        .uri("/thingmodel/set-device-property")
                        .header("Accept", "application/json, text/plain, */*")
                        .header("authorization", token)
                        .bodyValue(new SetDevicePropertyRequest(productId, deviceName, params))
                        .retrieve()
                        .bodyToMono(String.class)
                        .doOnNext(response -> {
                            logger.info("收到来自 OneNET 的响应: {}", response);
                        })
                        .doOnError(error -> {
                            logger.error("设置设备属性时发生错误", error);
                        }))
                .doOnSuccess(result -> {
                    logger.info("设备属性设置成功完成");
                })
                .doOnError(error -> {
                    logger.error("设备属性设置过程中发生错误", error);
                });
    }

    private static class SetDevicePropertyRequest {
        private String product_id;
        private String device_name;
        private Object params;

        public SetDevicePropertyRequest(String productId, String deviceName, Object params) {
            this.product_id = productId;
            this.device_name = deviceName;
            this.params = params;
        }

        public String getProduct_id() {
            return product_id;
        }

        public void setProduct_id(String product_id) {
            this.product_id = product_id;
        }

        public String getDevice_name() {
            return device_name;
        }

        public void setDevice_name(String device_name) {
            this.device_name = device_name;
        }

        public Object getParams() {
            return params;
        }

        public void setParams(Object params) {
            this.params = params;
        }
    }
}